home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / ArchiveUtils / nx_arc / arcadd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-20  |  9.0 KB  |  321 lines

  1. /*
  2.  * $Log:    arcadd.c,v $
  3.  * Revision 1.2  88/04/11  17:49:38  hyc
  4.  * formatting changes...
  5.  * 
  6.  * Revision 1.1  88/04/11  17:43:01  hyc
  7.  * Initial revision
  8.  * 
  9.  * Revision 1.1  87/12/19  04:00:40  hyc
  10.  * Initial revision
  11.  * 
  12.  * Revision 1.4  87/08/13  17:03:01  hyc
  13.  * Run thru the indent program...
  14.  *  Revision 1.3  87/07/21  11:39:49  hyc minor
  15.  * fixups
  16.  * 
  17.  * Revision 1.2  87/07/21  06:50:06  hyc *** empty log message ***
  18.  * 
  19.  */
  20.  
  21. /*
  22.  * ARC - Archive utility - ARCADD
  23.  * 
  24.  * Version 3.40, created on 06/18/86 at 13:10:18
  25.  * 
  26.  * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  27.  * 
  28.  * By:  Thom Henderson
  29.  * 
  30.  * Description: This file contains the routines used to add files to an archive.
  31.  * 
  32.  * Language: Computer Innovations Optimizing C86
  33.  */
  34. #include <stdio.h>
  35. #include "arc.h"
  36.  
  37. INT
  38. addarc(num, arg, move, update, fresh)        /* add files to archive */
  39.     INT             num;    /* number of arguments */
  40.     char           *arg[];    /* pointers to arguments */
  41. INT             move;        /* true if moving file */
  42. INT             update;        /* true if updating */
  43. INT             fresh;        /* true if freshening */
  44. {
  45.     char           *d, *dir();    /* directory junk */
  46.     char            buf[100];    /* pathname buffer */
  47.     char          **path = NULL;    /* pointer to pointers to paths */
  48.     char          **name = NULL;    /* pointer to pointers to names */
  49.     INT             nfiles = 0;    /* number of files in lists */
  50.     INT             notemp;    /* true until a template works */
  51.     INT             nowork = 1;    /* true until files are added */
  52.     char           *i, *rindex();    /* string indexing junk */
  53.     char           *malloc(), *realloc();    /* memory allocators */
  54.     INT             m, n;    /* indices */
  55.     unsigned INT    coreleft();    /* remaining memory reporter */
  56.     INT             addbunch();
  57.     INT             addfile();
  58.  
  59.     if (num < 1) {        /* if no files named */
  60.         num = 1;    /* then fake one */
  61. #ifdef MSDOS
  62.         arg[0] = "*.*";    /* add everything */
  63. #endif
  64. #ifdef BSD
  65.         arg[0] = "*";
  66. #endif
  67. #ifdef MTS
  68.         arg[0] = "?";
  69. #endif
  70.     }
  71.     path = (char **) malloc(sizeof(char **));
  72.     name = (char **) malloc(sizeof(char **));
  73.  
  74.  
  75.     for (n = 0; n < num; n++) {    /* for each template supplied */
  76.         strcpy(buf, arg[n]);    /* get ready to fix path */
  77. #ifndef MTS
  78.         if (!(i = rindex(buf, '\\')))
  79.             if (!(i = rindex(buf, '/')))
  80.                 if (!(i = rindex(buf, ':')))
  81.                     i = buf - 1;
  82. #else
  83.         if (!(i = rindex(buf, sepchr[0])))
  84.             if (buf[0] != tmpchr[0])
  85.                 i = buf - 1;
  86.             else
  87.                 i = buf;
  88. #endif
  89.         i++;        /* pointer to where name goes */
  90.  
  91.         notemp = 1;    /* reset files flag */
  92.         for (d = dir(arg[n], 0); d; d = dir(NULL, 0)) {
  93.             notemp = 0;    /* template is giving results */
  94.             nfiles++;    /* add each matching file */
  95.             path = (char **) realloc(path, nfiles * sizeof(char **));
  96.             name = (char **) realloc(name, nfiles * sizeof(char **));
  97.             strcpy(i, d);    /* put name in path */
  98.             path[nfiles - 1] = malloc(strlen(buf) + 1);
  99.             strcpy(path[nfiles - 1], buf);
  100.             name[nfiles - 1] = d;    /* save name */
  101. #ifdef MSDOS
  102.             if (coreleft() < 5120) {
  103.                 nfiles = addbunch(nfiles, path, name, move, update, fresh);
  104.                 nowork = nowork && !nfiles;
  105.                 while (nfiles) {
  106.                     free(path[--nfiles]);
  107.                     free(name[nfiles]);
  108.                 }
  109.                 free(path);
  110.                 free(name);
  111.                 path = name = NULL;
  112.             }
  113. #endif
  114.         }
  115.         if (notemp && warn)
  116.             printf("No files match: %s\n", arg[n]);
  117.     }
  118.  
  119.     if (nfiles) {
  120.         nfiles = addbunch(nfiles, path, name, move, update, fresh);
  121.         nowork = nowork && !nfiles;
  122.         while (nfiles) {
  123.             free(path[--nfiles]);
  124.             free(name[nfiles]);
  125.         }
  126.         free(path);
  127.         free(name);
  128.     }
  129.     if (nowork && warn)
  130.         printf("No files were added.\n");
  131. }
  132.  
  133. INT
  134. addbunch(nfiles, path, name, move, update, fresh)    /* add a bunch of files */
  135.     INT             nfiles;    /* number of files to add */
  136.     char          **path;    /* pointers to pathnames */
  137.     char          **name;    /* pointers to filenames */
  138.     INT             move;    /* true if moving file */
  139.     INT             update;    /* true if updating */
  140.     INT             fresh;    /* true if freshening */
  141. {
  142.     char            buf[100];    /* pathname buffer */
  143.     INT             m, n;    /* indices */
  144.     char           *d;    /* swap pointer */
  145.     struct heads    hdr;    /* file header data storage */
  146.  
  147.     for (n = 0; n < nfiles - 1; n++) {    /* sort the list of names */
  148.         for (m = n + 1; m < nfiles; m++) {
  149.             if (strcmp(name[n], name[m]) > 0) {
  150.                 d = path[n];
  151.                 path[n] = path[m];
  152.                 path[m] = d;
  153.                 d = name[n];
  154.                 name[n] = name[m];
  155.                 name[m] = d;
  156.             }
  157.         }
  158.     }
  159.  
  160.     for (n = 0; n < nfiles - 1;) {    /* consolidate the list of names */
  161.         if (!strcmp(path[n], path[n + 1])    /* if duplicate names */
  162.             ||!strcmp(path[n], arcname)    /* or this archive */
  163.             ||izadir(path[n])    /* or a directory */
  164.             ||!strcmp(path[n], newname)    /* or the new version */
  165.             ||!strcmp(path[n], bakname)) {    /* or its backup */
  166.             free(path[n]);    /* then forget the file */
  167.             free(name[n]);
  168.             for (m = n; m < nfiles - 1; m++) {
  169.                 path[m] = path[m + 1];
  170.                 name[m] = name[m + 1];
  171.             }
  172.             nfiles--;
  173.         } else
  174.             n++;    /* else test the next one */
  175.     }
  176.  
  177.     if (!strcmp(path[n], arcname)    /* special check for last file */
  178.         ||!strcmp(path[n], newname)    /* courtesy of Rick Moore */
  179.         ||izadir(path[n])
  180.         || !strcmp(path[n], bakname)) {
  181.         free(path[n]);
  182.         free(name[n]);
  183.         nfiles--;
  184.     }
  185.     if (!nfiles)        /* make sure we got some */
  186.         return 0;
  187.  
  188.     for (n = 0; n < nfiles - 1; n++) {    /* watch out for duplicate
  189.                          * names */
  190.         if (!strcmp(name[n], name[n + 1]))
  191.             arc_abort("Duplicate filenames:\n  %s\n  %s", path[n], path[n + 1]);
  192.     }
  193.     openarc(1);        /* open archive for changes */
  194.  
  195.     for (n = 0; n < nfiles; n++)    /* add each file in the list */
  196.         addfile(path[n], name[n], update, fresh);
  197.  
  198.     /* now we must copy over all files that follow our additions */
  199.  
  200.     while (readhdr(&hdr, arc)) {    /* while more entries to copy */
  201.         writehdr(&hdr, new);
  202.         filecopy(arc, new, hdr.size);
  203.     }
  204.     hdrver = 0;        /* archive EOF type */
  205.     writehdr(&hdr, new);    /* write out our end marker */
  206.     closearc(1);        /* close archive after changes */
  207.  
  208.     if (move) {        /* if this was a move */
  209.         for (n = 0; n < nfiles; n++) {    /* then delete each file
  210.                          * added */
  211.             if (unlink(path[n]) && warn) {
  212.                 printf("Cannot unsave %s\n", path[n]);
  213.                 nerrs++;
  214.             }
  215.         }
  216.     }
  217.     return nfiles;        /* say how many were added */
  218. }
  219.  
  220. static          INT
  221. addfile(path, name, update, fresh)    /* add named file to archive */
  222.     char           *path;    /* path name of file to add */
  223.     char           *name;    /* name of file to add */
  224.     INT             update;    /* true if updating */
  225.     INT             fresh;    /* true if freshening */
  226. {
  227.     struct heads    nhdr;    /* data regarding the new file */
  228.     struct heads    ohdr;    /* data regarding an old file */
  229.     FILE           *f, *fopen();    /* file to add, opener */
  230.     LONG            starts, ftell();    /* file locations */
  231.     INT             c;    /* one char of file */
  232.     INT             upd = 0;/* true if replacing an entry */
  233.  
  234. #ifndef MTS
  235.     if (!(f = fopen(path, "r"))) {
  236. #else
  237.     if (image)
  238.         f = fopen(path, "rb");
  239.     else
  240.         f = fopen(path, "r");
  241.     if (!f) {
  242. #endif
  243.         if (warn) {
  244.             printf("Cannot read file: %s\n", path);
  245.             nerrs++;
  246.         }
  247.         return;
  248.     }
  249.     strcpy(nhdr.name, name);/* save name */
  250.     nhdr.size = 0;        /* clear out size storage */
  251.     nhdr.crc = 0;        /* clear out CRC check storage */
  252. #ifndef MTS
  253.     getstamp(f, &nhdr.date, &nhdr.time);
  254. #else
  255.     getstamp(path, &nhdr.date, &nhdr.time);
  256. #endif
  257.  
  258.     /* position archive to spot for new file */
  259.  
  260.     if (arc) {        /* if adding to existing archive */
  261.         starts = ftell(arc);    /* where are we? */
  262.         while (readhdr(&ohdr, arc)) {    /* while more files to check */
  263.             if (!strcmp(ohdr.name, nhdr.name)) {
  264.                 upd = 1;    /* replace existing entry */
  265.                 if (update || fresh) {    /* if updating or
  266.                              * freshening */
  267.                     if (nhdr.date < ohdr.date
  268.                         || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) {
  269.                         fseek(arc, starts, 0);
  270.                         fclose(f);
  271.                         return;    /* skip if not newer */
  272.                     }
  273.                 }
  274.             }
  275.             if (strcmp(ohdr.name, nhdr.name) >= 0)
  276.                 break;    /* found our spot */
  277.  
  278.             writehdr(&ohdr, new);    /* entry preceeds update;
  279.                          * keep it */
  280.             filecopy(arc, new, ohdr.size);
  281.             starts = ftell(arc);    /* now where are we? */
  282.         }
  283.  
  284.         if (upd) {    /* if an update */
  285.             if (note) {
  286.                 printf("Updating file: %-12s  ", name);
  287.                 fflush(stdout);
  288.             }
  289.             fseek(arc, ohdr.size, 1);
  290.         } else if (fresh) {    /* else if freshening */
  291.             fseek(arc, starts, 0);    /* then do not add files */
  292.             fclose(f);
  293.             return;
  294.         } else {    /* else adding a new file */
  295.             if (note) {
  296.                 printf("Adding file:   %-12s  ", name);
  297.                 fflush(stdout);
  298.             }
  299.             fseek(arc, starts, 0);    /* reset for next time */
  300.         }
  301.     } else {        /* no existing archive */
  302.         if (fresh) {    /* cannot freshen nothing */
  303.             fclose(f);
  304.             return;
  305.         } else if (note) {    /* else adding a file */
  306.             printf("Adding file:   %-12s  ", name);
  307.             fflush(stdout);
  308.         }
  309.     }
  310.  
  311.     starts = ftell(new);    /* note where header goes */
  312.     hdrver = 8;        /* anything but end marker */
  313.     writehdr(&nhdr, new);    /* write out header skeleton */
  314.     pack(f, new, &nhdr);    /* pack file into archive */
  315.     strcpy(nhdr.name, name);
  316.     fseek(new, starts, 0);    /* move back to header skeleton */
  317.     writehdr(&nhdr, new);    /* write out real header */
  318.     fseek(new, nhdr.size, 1);    /* skip over data to next header */
  319.     fclose(f);        /* all done with the file */
  320. }
  321.